package com.example.leetcode.prcatice;

/**
 * 有一堆石头，用整数数组 stones 表示。其中 stones[i] 表示第 i 块石头的重量。
 *
 * <p>每一回合，从中选出任意两块石头，然后将它们一起粉碎。假设石头的重量分别为 x 和 y，且 x <= y。那么粉碎的可能结果如下：
 *
 * <p>如果 x == y，那么两块石头都会被完全粉碎； 如果 x != y，那么重量为 x 的石头将会完全粉碎，而重量为 y 的石头新重量为 y-x。 最后，最多只会剩下一块 石头。返回此石头
 * 最小的可能重量 。如果没有石头剩下，就返回 0。
 *
 * <p>
 *
 * <p>示例 1：
 *
 * <p>输入：stones = [2,7,4,1,8,1] 输出：1 解释： 组合 2 和 4，得到 2，所以数组转化为 [2,7,1,8,1]， 组合 7 和 8，得到 1，所以数组转化为
 * [2,1,1,1]， 组合 2 和 1，得到 1，所以数组转化为 [1,1,1]， 组合 1 和 1，得到 0，所以数组转化为 [1]，这就是最优值
 *
 */
public class Test1049 {

    /**
     * dp[i][j] 表示可选石头为前i个时，容量为j的背包所能存放的实际最大值
     * @param stones
     * @return
     */
    public int lastStoneWeightII(int[] stones) {
    int length = stones.length;
    int sum = 0;
    for ( int i:stones ) {
        sum += i;
    }
    int[][]dp = new int[length+1][sum/2+1];
        for(int i=1;i<=length;i++){
            for(int j=0;j<=sum/2;j++){
                //当我能把这块石头放进背包时，我会比较放或不放，选择最大值
                if(j>=stones[i-1]){
                    dp[i][j] = Math.max(dp[i-1][j],dp[i-1][j-stones[i-1]] + stones[i-1]);
                } else {
                    //这块石头放不进背包时，只能跳过
                    dp[i][j] = dp[i-1][j];
                }
            }
        }
        //dp[n][sum/2]的最大值为sum/2，因此最理想的结果为0
        return sum-dp[length][sum/2]*2;

}
  //[1,1,2,3,5,8,13,21,34,55,89,14,23,37,61,98]
}
class Test2{
  public static void main(String[] args) {
    Test1049 test1049 = new Test1049();
    int[] i = {1,1,2,3,5,8,13,21,34,55,89,14,23,37,61,98};
    System.out.println(test1049.lastStoneWeightII(i));
  }
}

//for(int i=1;i<=n;i++){
//         for(int j=0;j<=sum/2;j++){
//         //当我能把这块石头放进背包时，我会比较放或不放，选择最大值
//         if(j>=stones[i-1]){
//         dp[i][j] = Math.max(dp[i-1][j],dp[i-1][j-stones[i-1]] + stones[i-1]);
//         } else {
//         //这块石头放不进背包时，只能跳过
//         dp[i][j] = dp[i-1][j];
//         }
//         }
//         }
//         //dp[n][sum/2]的最大值为sum/2，因此最理想的结果为0
//         return sum-dp[n][sum/2]*2;


